package com.fanfanwang.ffw.app.crash;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;
import java.util.HashMap;

import com.fanfanwang.ffw.app.AppConstant;
import com.fanfanwang.ffw.app.tools.FileUtils;
import com.fanfanwang.ffw.app.tools.TimeUtils;



import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.os.Looper;
import android.util.Log;
import android.view.Gravity;
import android.widget.Toast;



public class CrashHandler implements UncaughtExceptionHandler {

	
	public static final String TAG = "CrashHandler";
	// 系统默认的UncaughtException处理类
	private Thread.UncaughtExceptionHandler mDefaultHandler;
	// CrashHandler实例
	private static CrashHandler INSTANCE = new CrashHandler();
	private Context mContext;
	// 用来存储设备信息和异常信息
	private HashMap<String, String> infos = new HashMap<String, String>();

	private CrashHandler() {
		
	}

	/** 获取CrashHandler实例 */
	public static CrashHandler getInstance() {
		return INSTANCE;
	}

	/**
	 * 初始化
	 * 
	 * @param mContext
	 */
	public void init(Context mContext) {
		this.mContext = mContext;
		// 获得系统默认的UncaughtException处理器
		mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
		// 设置该CrashHandler为程序默认的处理器
		Thread.setDefaultUncaughtExceptionHandler(this);
	}
	
	public void uncaughtException(Thread thread, Throwable ex) {
		Log.e("uncaughtException", "uncaughtException..............");
		ex.printStackTrace();
		
		new Thread() {//提示
			public void run() {
				Looper.prepare();
				Toast toast = Toast.makeText(mContext, "亲，隐藏一下",
						Toast.LENGTH_LONG);
				toast.setGravity(Gravity.CENTER, 0, 110);
				toast.show();
				
				Looper.loop();
			};
		}.start();
		
		
		//得到错误信息
		String errorContent = getErrorContent(ex);
		ErrorInfo errorInfo = new ErrorInfo();
		errorInfo.setErrorContent(errorContent);
		errorInfo.setErrorTitle(ex.getLocalizedMessage());
		errorInfo.setErrorTime(""+System.currentTimeMillis());
		
		if (!handleException(ex) && mDefaultHandler != null) {
			// 如果用户没有处理则让系统默认的异常处理器来处理
			mDefaultHandler.uncaughtException(thread, ex);
		} 
//		else {
//			try {//上传到服务器,上传成功后退出程序
//				ConnectivityManager cm = (ConnectivityManager) this.mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
//				NetworkInfo info = cm.getActiveNetworkInfo();
//
//				if (info != null && info.isAvailable()) {
//					String imei = ((TelephonyManager) this.mContext
//							.getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId();
////					//修改登出信息
////					CollectStatistics cs = new CollectStatistics(Util.APP_NAME);
////					cs.updateLogoutInfo();
////					cs.close();
////					cs = null;
//					//上传错误信息
////					UploadCrashInfoTool uci = new UploadCrashInfoTool();
////					uci.upLoadErrorInfo();
////					uci.close();
////					uci = null;
////					infos.clear();
////					infos = null;
//				}
//			} catch (Exception e) {
//				
//			}finally{
//				CrashApplication.getInstance().exitProgram();
//			}
//		}
	}


	/**
	 * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
	 * 
	 * @param ex
	 * @return true:如果处理了该异常信息;否则返回false.
	 */
	private boolean handleException(Throwable ex) {
		if (ex == null) {
			return false;
		}
		new Thread() {
			public void run() {
				Looper.prepare();
//				Toast toast = Toast.makeText(mContext, "很抱歉,程序出现异常即将退出",
				Toast toast = Toast.makeText(mContext, "很抱歉,程序出现异常即将退出",
						Toast.LENGTH_LONG);
				toast.setGravity(Gravity.CENTER, 0, 110);
				toast.show();
				
				Looper.loop();
			};
		}.start();
//		collectDeviceInfo(mContext);
		saveCrashInfo(ex);
		return true;
	}
	
	/**
	 * 收集设备信息
	 */
	public void collectDeviceInfo(Context context) {
		try {
			PackageManager pm = context.getPackageManager();
			PackageInfo pi = pm.getPackageInfo(context.getPackageName(),
					PackageManager.GET_ACTIVITIES);
			if (pi != null) {
//				SharedPreferencesManager shpm = new SharedPreferencesManager(context);
//				String versionName = pi.versionName == null ? "null"
//						: pi.versionName;
//				String versionCode = pi.versionCode + "";
//				infos.put("IMEI", shpm.getImei(SharedPreferencesManager.IMEI));
//				infos.put("versionName", versionName);
//				infos.put("versionCode", versionCode);
//				infos.put("width", Integer.toString(shpm.getWidth(SharedPreferencesManager.SCREEN_WIDTH)));
//				infos.put("height", Integer.toString(shpm.getHeight(SharedPreferencesManager.SCREEN_HEIGHT)));
//				infos.put("phoneNumber", ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE)).getLine1Number());
//				infos.put("display", Build.DISPLAY);
//				shpm.close();
//				shpm = null;
			}
			pi = null;
			pm = null;
		} catch (NameNotFoundException e) {
//			Print.e("",TAG, "an error occured when collect package info", e);
//			sendQuitBroadcast();
		}
		Field[] fields = Build.class.getDeclaredFields();
		for (Field field : fields) {
			try {
				field.setAccessible(true);
				infos.put(field.getName(), field.get(null).toString());
				Log.e("",field.getName() + " : " + field.get(null));
			} catch (Exception e) {
//				Print.e("",TAG, "an error occured when collect crash info", e);
			}
		}
		infos.put("sdkversion", Build.VERSION.SDK);
		infos.put("osversion", Build.VERSION.RELEASE);
		fields = null;
	}

	//保存错误信息到文件
	private void saveCrashInfo(Throwable ex) {
		StringBuffer sb = new StringBuffer();
		
		Writer writer = new StringWriter();
		PrintWriter printWriter = new PrintWriter(writer);
		ex.printStackTrace(printWriter);
		Throwable cause = ex.getCause();
		while (cause != null) {
			cause.printStackTrace(printWriter);
			cause = cause.getCause();
		}
		printWriter.close();
		String result = writer.toString();
		try {
			writer.close();
		} catch (IOException e) {
//			Print.v("","[Test]", e.getMessage());
		}
		writer = null;
		sb.append(result);
		Log.e("","---saveCrashInfo------>"+ sb.toString());
		//得到错误标题
		String errorTitle = ex.getLocalizedMessage();
		ErrorInfo errorInfo = new ErrorInfo();
		errorInfo.setErrorContent(sb.toString());
		errorInfo.setErrorTitle(errorTitle);
//		ErrorManager errorManager = new ErrorManager();
//		long insertId = errorManager.insert(errorInfo);
//		if(insertId >= 0){
//			Log.i("","insertId"+ "错误信息插入成功");
//		}
//		errorManager.close();
//		errorManager = null;
		StringBuffer sbLog = new StringBuffer();
		sbLog.append("errprTitle  :  ").append(errorInfo.getErrorTitle());
		sbLog.append("\\n");
		sbLog.append("errprContent  :  ").append(errorInfo.getErrorContent());
		sbLog.append("\\n");
		sbLog.append("errprTime  :  ").append(TimeUtils.getFormatDate1());
		InputStream input = new ByteArrayInputStream(sbLog.toString().getBytes());
		FileUtils.writeSDFromInput(AppConstant.LOG_CHCHE, System.currentTimeMillis()+".txt", input);
	}
	
	private String getErrorContent(Throwable ex){
		StringBuffer sb = new StringBuffer();
		
		Writer writer = new StringWriter();
		PrintWriter printWriter = new PrintWriter(writer);
		ex.printStackTrace(printWriter);
		Throwable cause = ex.getCause();
		while (cause != null) {
			cause.printStackTrace(printWriter);
			cause = cause.getCause();
		}
		printWriter.close();
		String result = writer.toString();
		try {
			writer.close();
		} catch (IOException e) {
//			Print.v("","[Test]", e.getMessage());
		}
		writer = null;
		sb.append(result);
		
		return sb.toString();
		
//		new UploadLoginInfoTool().test();
//		new UploadCrashInfoTool().test();
	}
}
